#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <iostream>

using namespace std;

int main() {
  //   cout << "hello world" << endl;
  pid_t id = fork();
  if (id == 0) {
    // 子进程

    /*
        //execl的使用方法:

        //  execl("/usr/bin/ls", "ls","-a","-l","-i", NULL);//
        const char* path = "/usr/bin/ls";
        const char* arg = "ls";
        execl(path, arg, "-a", "-l", "-i", NULL);
    */

    /*
        //execlp使用方法:

        // execlp("ls", "ls", "-a", "-l", nullptr);
       //可直接使用环境变量,无需给定路径 execlp("/usr/bin/ls", "ls", "-a", "-l",
       nullptr);
    */

    /*
        //execle 的使用方法:

        //execle 与execl类似 唯一不同的是execl可以指定对应的环境变量
        // execle("/bin/ls", "ls", "-a", "-l", nullptr);
        const char* envp[] = {"PATH=/bin"};
        execle("/bin/ls", "ls", "-a", "-l", nullptr,envp);
    */

    /*
        //execv 的使用方法:
        // execv的使用方法与execl类似,唯一不同的是在传参的过程中 execv的参数需要以数组的形式传递而不是以可变参数的形式传递
        char* const args[] = {(char*)"ls", (char*)"-a", (char*)"-l", (char*)"-i",
                          nullptr};
        execv("/bin/ls", args); 
    */

    /* 
      //execvp 的调用方法:
      //execvp的调用方法类似execv 唯一不同的是execvp的第一个参数编译器将优先在$PATH环境变量中查找
    
      char* const args[] = {(char*)"ls", (char*)"-a", (char*)"-l", nullptr};
      // execvp("ls", args);
      execvp("/bin/ls", args);
     */


    /*
      //execvpe 的调用方法：
      //execvpe 的调用方法类似于 execvp 的调用 
      //唯一不同的是execvpe的调用允许传递额外的环境变量 若是不希望传额外的环境变量则需要在envp位置使用NULL
      
      char* const args[] = {(char*)"ls", (char*)"-a", (char*)"-l", nullptr};
      char* const envp[] = {(char*)"PATH=/bin"};
      // execvpe("ls",args,NULL);   //envp可省略为NULL
      execvpe("ls",args,envp);
    */

    char* args[] = {(char*)"ls", (char*)"-a", (char*)"-l", (char*)"-a",nullptr};
    // execve("/usr/bin/ls", args,NULL);//不传递环境变量
    char* envp[] = {(char*)"PATH=/usr/local/bin", nullptr};
    execve("/bin/ls",args,envp);//传递参数数组和环境变量数组
    //execve与其余函数不同属于是系统级别的系统调用
    //其他函数在调用的过程中都需要调用该函数
    //其他函数本质上属于该函数的封装后的函数



    exit(0);
  } else if (id > 0) {
    // 父进程
    pid_t status = 0;
    waitpid(-1, &status, 0);
    cout << "父进程 退出码: " << WEXITSTATUS(status) << endl;
  } else {
    // 进程创建失败
    cerr << "fork()" << endl;
  }
  return 0;
}